open Ast
open Bytecode
open Printf

let execute_prog prog=
let out = Array.make 2000 "0" in 
                        let stack=Array.make 500 "0" 
                        and globals = Array.make prog.num_globals "0"
                        in let rec exec fp sp pc=match prog.text.(pc) with
                        
| Push i ->stack.(sp)<-i; exec fp (sp+1) (pc+1)  

| Hlt-> let oc=open_out "test1.mxml"  in fprintf oc "%s\n"  "<?xml version=\"1.0\" encoding=\"utf-8\"?>" ; fprintf oc "%s\n"  "<s:Application xmlns:fx=\"http://ns.adobe.com/mxml/2009\""; fprintf oc "%s\n"  "xmlns:s=\"library://ns.adobe.com/flex/spark\""; fprintf oc "%s\n"  "xmlns:mx=\"library://ns.adobe.com/flex/mx\" minWidth=\"955\" minHeight=\"600\">";
fprintf oc "%s\n"  "<mx:VBox height=\"492\" x=\"48\" y=\"16\" width=\"624\">";

let w= ref 0 in
while( out.(!w).[0]!='0') do(fprintf oc "%s\n" out.(!w); w:=!w+1) done;
fprintf oc "%s\n"  "</mx:VBox>";
fprintf oc "%s\n"  "</s:Application>";


close_out oc;
 ()  
 
|GlJpwb(i, j)-> exec fp sp (pc+1)
|LoJpwb(i,j)->exec fp sp (pc+1)
|GlLkwb(i,j)->exec fp sp (pc+1)
|LoLkwb(i,j)->exec fp sp (pc+1)
|Lod (i)->exec fp sp (pc+1)

|Glwbt (i,j,k)-> globals.(i)<- k ; globals.(i+2) <- j;  globals.(fp+i) <- string_of_int i; exec fp sp (pc+1)

(*write back the global answer, i is the length*)

|Glwba(i,j)-> globals.(i+4) <- string_of_int j; exec fp sp  (pc+1)

(*global text write back*)

|Gltwbt (i,j) -> globals.(i+3) <- string_of_int j; globals.(i+4) <- string_of_int 4; exec fp sp (pc+1)

(*3 is the place that we preserve the length information*)

| Pushag (i,j)-> let al = ref (i+5) in
                        let a=while (globals.(!al).[0] !='0') do (al:=!al+1) done;
                            (!al) in globals.(a) <-j;
                            globals.(i+3) <-string_of_int ((int_of_string globals.(i+3))+1);
                        exec fp sp (pc+1);

| Lowbt (i,j,k)-> stack.(fp+i+1)<- k; stack.(fp+i+2)<- j; stack.(fp+i)<- string_of_int 1; exec fp sp (pc+1)
 | Lowba(i, j)-> stack.(fp+i+4)<- string_of_int  j ; exec fp sp (pc+1)    
 | Lotwbt (i,j) -> stack.(fp+i+3) <- string_of_int j;stack.(fp+i+4)<- string_of_int 4; exec fp sp (pc+1) 
 | Loqswb (i,j) -> let ii= ref (i+fp) in let iii=  while( (int_of_string stack.(!ii))!= 0) do (ii:= (int_of_string stack.( (!ii))))  done ; !ii in stack.(iii) <- string_of_int sp ; stack.(iii+1)<- string_of_int j; exec fp (sp+2) (pc+1)  
 | Loquetrace i -> stack.(sp) <- string_of_int i; exec fp (sp+1) (pc+1) 
|Jsr i-> stack.(sp)<-string_of_int  (pc+1); exec fp (sp+1) i;
| Ent i-> stack.(sp)<-string_of_int fp; exec sp (sp+i+1) (pc+1);
| Rts i ->let new_fp= stack.(fp) and new_pc=stack.(fp-1) in exec (int_of_string new_fp) (fp-i) (int_of_string new_pc)
| Pushal ( i, j)-> let al= ref (fp+i+5) in let a= while (stack.(!al).[0]!='0') do(al:=!al+1) done; (!al) in stack.(a)<- j; stack.(fp+i+3)<-string_of_int ((int_of_string stack.(fp+i+3))+1);
exec fp sp (pc+1);

| Lfp i-> if(stack.(fp+i).[0]='1') then (let lf=ref 0 in while(!lf<13) do(stack.(sp+(!lf))<- stack.(fp+i+(!lf));lf:=!lf+1) done;) else(); exec  fp (sp+13) (pc+1)

| Loshow i-> let ij=ref (fp+i) in while( int_of_string stack.(int_of_string stack.(!ij)+1)!=0) 
do ( 
 let ii=ref 0 in let iii= while((out.(!ii).[0])!='0') do (ii:=!ii+1) done;
 !ii in 
out.(iii)<-"<mx:HBox>";  out.(iii+1)<- "<mx:Label text=\"" ^  stack. (int_of_string stack.(int_of_string stack.((!ij))+2)+1+fp)

^"\"/>";
 out.(iii+2)<-  "<mx:Label text=\"" ^ stack. (int_of_string stack.(int_of_string stack.((!ij))+2)+2+fp)
 ^"\"/>";
 out.(iii+3)<- "</mx:HBox>";
if ( (int_of_string stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+4+fp))==1) 
then (let j=ref 0 in 
(while(!j<(int_of_string stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+3+fp))) 

do (out.(iii+(!j)+4)<- "<s:RadioButton label=\"" ^ stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+5+fp+(!j))

^"\" />";j:=!j+1;)     
 done) ) else ();

if((int_of_string stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+4+fp))==2) then 
(let jj=ref 0 in 
(while(!jj<(int_of_string stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+3+fp))) 
do (out.(iii+(!jj)+4)<- "<s:CheckBox label=\"" ^ stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+5+fp+(!jj))
^ "\"/>";jj:=!jj+1;) 
done)
) else();
if((int_of_string stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+4+fp))==4) 

then(out.(iii+4)<-"<mx:TextArea height=\"21\" width=\"" ^  string_of_int ((int_of_string stack.(int_of_string stack.( int_of_string stack.((!ij))+2)+3+fp))*10)      ^"\"/>"

) else(); ij:=int_of_string stack.(!ij); ) done;

let ii=ref 0 in let iiii= while((out.(!ii).[0])!='0') do (ii:=!ii+1) done;
 !ii in 
out.(iiii)<-"<mx:HBox>";  out.(iiii+1)<- "<mx:Label text=\"" ^ stack.(fp+int_of_string stack.(int_of_string stack.((!ij))+2)+1)

^"\"/>";
 out.(iiii+2)<-  "<mx:Label  text=\"" ^ stack. (fp+int_of_string stack.(int_of_string stack.((!ij))+2)+2)
 ^"\"/>";
 out.(iiii+3)<- "</mx:HBox>";
if ( (int_of_string stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+4+fp))==1) 
then (let j=ref 0 in 
(while(!j<(int_of_string stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+3+fp))) 
do (out.(iiii+(!j)+4)<- "<s:RadioButton label=\"" ^ stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+5+fp+(!j))

^"\" />";j:=!j+1;)     
 done) ) else ();



if((int_of_string stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+4+fp))==2) then 
(let jj=ref 0 in 
(while(!jj<(int_of_string stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+3+fp))) 
do (out.(iiii+(!jj)+4)<- "<s:CheckBox label=\"" ^ stack.(int_of_string stack.( int_of_string stack.((!ij))+2)+5+(!jj))
^ "\"/>";jj:=!jj+1;) 
done)
) else();
if((int_of_string stack.(int_of_string stack.(int_of_string stack.((!ij))+2)+4+fp))==4) then(out.(iiii+4)<-"<mx:TextArea height=\"21\" width=\"" ^  string_of_int ((int_of_string stack.(int_of_string stack.( int_of_string stack.(!ij)+2)+3+fp))*10)     ^"\"/>"
) else();




exec fp sp (pc+1)



in exec 0 0 0;;
